package com.yuntu.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuntu.api.code.phone.SendSmsExample;
import com.yuntu.demo.dto.user.UserLoginRequest;
import com.yuntu.demo.dto.user.UserQueryRequest;
import com.yuntu.demo.dto.user.UserRegisterRequest;
import com.yuntu.demo.entity.User;
import com.yuntu.demo.enums.UserRoleEnum;
import com.yuntu.demo.vo.LoginUserVO;
import com.yuntu.demo.vo.UserVO;
import com.yuntu.exception.ErrorCode;
import com.yuntu.exception.ThrowUtils;
import com.yuntu.exception.bizException;
import com.yuntu.manager.auth.StpKit;
import com.yuntu.mapper.UserMapper;
import com.yuntu.service.IUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.yuntu.demo.constant.UserConstant.USER_LOGIN_STATE;

/**
 * <p>
 * 用户 服务实现类
 * </p>
 *
 * @author k
 * @since 2025-03-19
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Resource
    UserMapper userMapper;
    @Resource
    SendSmsExample sendSmsExample;
    @Resource
    RedisTemplate redisTemplate;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public long register(UserRegisterRequest user) {
        ThrowUtils.throwIf(user==null, ErrorCode.NOT_FOUND_ERROR);
        String userAccount = user.getUserAccount();
        String userPassword = user.getUserPassword();
        String checkPassword = user.getCheckPassword();
        //两次密码是否一致
        ThrowUtils.throwIf(!userPassword.equals(checkPassword),new bizException(-1,"两次密码不一致"));
        //账户是否存在
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserAccount, userAccount);
        User reuser = userMapper.selectOne(queryWrapper);
        ThrowUtils.throwIf(reuser!=null,new bizException(-2,"账号已经存在"));
        queryWrapper.eq(User::getPhone,user.getPhone());
        if(this.getOne(queryWrapper)!=null){
            throw new bizException(-1,"手机号已被注册");
        }
        //验证码是否正确
        String code = (String) redisTemplate.opsForValue().get(user.getPhone());
        ThrowUtils.throwIf(code==null,new bizException(-3,"未获取验证码"));
        ThrowUtils.throwIf(!code.equals(user.getCheckCode()),new bizException(-4,"验证码错误"));
        //加入数据库
        User registUser = new User();
        registUser.setUserAccount(userAccount);
        registUser.setUserPassword(getPwd(userPassword));
        registUser.setEditTime(LocalDateTime.now());
        registUser.setCreateTime(LocalDateTime.now());
        registUser.setPhone(user.getPhone());
        //默认昵称为账号
        registUser.setUserName(user.getUserAccount());
        //默认头像
        registUser.setUserAvatar("https://yuntuku-1349942352.cos.ap-guangzhou.myqcloud.com/public/1907052644782452738/2025-04-01_KIKTlV2SV8vKUVnl.webp");
        boolean save = this.save(registUser);
        ThrowUtils.throwIf(save==false,new bizException(-3,"数据库出错"));
        return registUser.getId();
    }

    @Override
    public String getPwd(String pwd) {
        //加盐
        String yan="xiaok";
        return DigestUtils.md5DigestAsHex((yan+pwd).getBytes());
    }
    @Override
    public LoginUserVO login(UserLoginRequest user, HttpSession session) {
        //判断是否存在
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserAccount, user.getUserAccount());
        queryWrapper.eq(User::getUserPassword, getPwd(user.getUserPassword()));
        User loginUser = userMapper.selectOne(queryWrapper);
        ThrowUtils.throwIf(loginUser==null,new bizException(-1,"账号或密码错误"));
        //转换为vo
        LoginUserVO loginUserVO = new LoginUserVO();
        BeanUtils.copyProperties(loginUser,loginUserVO);
        //存入session
        session.setAttribute(USER_LOGIN_STATE,loginUserVO);
        //存入Sa-Token的登录态中
        //记录用户的登录态
        // 记录用户登录态到 Sa-token，便于空间鉴权时使用，注意保证该用户信息与 SpringSession 中的信息过期时间一致
        StpKit.SPACE.login(loginUserVO.getId());
        StpKit.SPACE.getSession().set(USER_LOGIN_STATE, loginUserVO);
        return loginUserVO;
    }

    /**
     * user脱敏
     * @param user 脱敏前的信息
     * @return
     */
    @Override
    public UserVO getUserVO(User user) {
        if (user == null) {
            return null;
        }
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return userVO;
    }
    /**
     * user列表脱敏
     * @param userList 脱敏前的信息
     * @return
     */
    @Override
    public List<UserVO> getUserVOList(List<User> userList) {
        if (CollectionUtils.isEmpty(userList)) {
            return new ArrayList<>();
        }
        return userList.stream().map(this::getUserVO).collect(Collectors.toList());
    }

    /**
     * 生成查询条件
     * @param userQueryRequest 查询条件
     * @return
     */
    @Override
    public QueryWrapper<User> getQueryWrapper(UserQueryRequest userQueryRequest) {
        if (userQueryRequest == null) {
            throw new bizException(ErrorCode.PARAMS_ERROR, "请求参数为空");
        }
        Long id = userQueryRequest.getId();
        String userAccount = userQueryRequest.getUserAccount();
        String userName = userQueryRequest.getUserName();
        String userProfile = userQueryRequest.getUserProfile();
        String userRole = userQueryRequest.getUserRole();
        String sortField = userQueryRequest.getSortField();
        String sortOrder = userQueryRequest.getSortOrder();
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(Objects.nonNull(id), "id", id);
        queryWrapper.eq(StrUtil.isNotBlank(userRole), "userRole", userRole);
        queryWrapper.like(StrUtil.isNotBlank(userAccount), "userAccount", userAccount);
        queryWrapper.like(StrUtil.isNotBlank(userName), "userName", userName);
        queryWrapper.like(StrUtil.isNotBlank(userProfile), "userProfile", userProfile);
        queryWrapper.orderBy(StringUtils.isNoneBlank(sortField), sortOrder.equals("ascend"), sortField);
        return queryWrapper;
    }
    @Override
    public LoginUserVO getLoginUser(HttpServletRequest request) {
        // 先判断是否已登录
        Object userObj = request.getSession().getAttribute(USER_LOGIN_STATE);
        LoginUserVO currentUser = (LoginUserVO) userObj;
        if (currentUser == null || currentUser.getId() == null) {
            throw new bizException(ErrorCode.NOT_LOGIN_ERROR);
        }
        // 从数据库查询（追求性能的话可以注释，直接返回上述结果）
//        long userId = currentUser.getId();
//        currentUser = this.getById(userId);
//        if (currentUser == null) {
//            throw new bizException(ErrorCode.NOT_LOGIN_ERROR);
//        }
        return currentUser;
    }

    @Override
    public boolean isAdmin(LoginUserVO user) {
        return user != null && UserRoleEnum.ADMIN.getValue().equals(user.getUserRole());
    }

    @Override
    public String getCode(String phone) {
        QueryWrapper queryWrapper = new QueryWrapper();
//        queryWrapper.eq("phone",phone);
//        if(this.getOne(queryWrapper)!=null){
//            throw new bizException(-1,"手机号已被注册");
//        }
        if(phone.length()!=11){
            throw new bizException(-1,"手机号格式错误");
        }
        String code = sendSmsExample.sendMsg(phone);
        //存入redis
        redisTemplate.opsForValue().set(phone,code,2, TimeUnit.MINUTES);
        return code;
    }

}
